// Copyright (C) 2021 Focus Media Holding Ltd. All Rights Reserved.

package cn.focusmedia.central.${appCode}.domain.${modelPackName}.service;


import java.util.List;

import org.apache.skywalking.apm.toolkit.trace.Trace;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.focusmedia.central.${appCode}.client.dto.${modelPackName}.${className}AddDTO;
import cn.focusmedia.central.${appCode}.client.dto.${modelPackName}.${className}DeleteDTO;
import cn.focusmedia.central.${appCode}.client.dto.${modelPackName}.${className}UpdateDTO;
import cn.focusmedia.central.${appCode}.domain.${modelPackName}.convert.${className}DomainConvert;
import cn.focusmedia.central.${appCode}.domain.${modelPackName}.domainobject.${className};
import cn.focusmedia.central.${appCode}.domain.${modelPackName}.domainobject.query.${className}Query;
import cn.focusmedia.central.${appCode}.tunnel.dao.${modelPackName}.${className}DAO;
import cn.focusmedia.central.${appCode}.tunnel.dataobject.${modelPackName}.${className}DO;
import cn.focusmedia.fdf.common.dto.MultiResponse;
import cn.focusmedia.fdf.common.dto.SingleResponse;
import cn.focusmedia.fdf.distributed.lock.LockKey;
import cn.focusmedia.fdf.distributed.lock.WithLock;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
* ${className}DomainService
*
* @author ${author}
* @since ${date}
**/
@Service
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ${className}DomainService {

    private final ${className}DAO ${objectName}DAO;

    private final ${className}DomainConvert ${objectName}Convert;

    @Trace(operationName = "${className} query")
    public MultiResponse<${className}> query(${className}Query query) {

        ${className}DO ${objectName}DO = ${objectName}Convert.convertQuery2DO(query);
        ${existQueryDeleteFlag0}
        ${existQueryValidStatus}
        List<${className}DO> ${objectName}DOList = ${objectName}DAO.getQueryMapper()
                .query(${objectName}DO, query.getPageNum(), query.getPageSize());
        int total = ${objectName}DOList.size();
        if (query.getPageSize() > 0) {
            total = ${objectName}DAO.count(${objectName}DO);
        }
        List<${className}> domainList = ${objectName}Convert.doList2DomainList(${objectName}DOList);
        return MultiResponse.of(domainList, total);

    }

    /**
    * 新增
    *
    * @param param  param
    * @return cn.focusmedia.central.domain.constant.SingleResponse
    * @author ${author}
    * @since  ${date}
    **/
    @Trace(operationName = "${className} add")
    public SingleResponse<${className}> add(${className}AddDTO param) {

        ${className} ${objectName} = new ${className}();
        BeanUtils.copyProperties(param, ${objectName});
        ${existDataVersion}
        ${existDeleteFlag0}
        ${existValidStatus}
        Long id = this.${objectName}DAO.add(this.${objectName}Convert.domain2DO(${objectName}));
        ${objectName}.setId(id);
        return SingleResponse.of(${objectName});

    }

    /**
    * 更新(redis锁)
    *
    * @param param param
    * @return cn.focusmedia.central.domain.constant.SingleResponse
    * @author ${author}
    * @since  ${date}
    **/
    @WithLock(expireAfter = 30000L, prefix = "${className}Update:")
    @Trace(operationName = "${className} update")
    public SingleResponse<${className}> update(@LockKey("id") ${className}UpdateDTO param) {

        ${className} ${objectName} = new ${className}();
        BeanUtils.copyProperties(param, ${objectName});
        this.${objectName}DAO.getCommandMapper()
                .updateByPrimaryKeySelective(this.${objectName}Convert.domain2DO(${objectName}));
        return SingleResponse.of(${objectName});

    }

    /**
    * 删除(redis锁)
    *
    * @param param param
    * @return cn.focusmedia.central.domain.constant.SingleResponse
    * @author ${author}
    * @since  ${date}
    **/
    @WithLock(expireAfter = 30000L, prefix = "${className}Delete:")
    @Trace(operationName = "${className} delete")
    public SingleResponse<${className}> delete(@LockKey("id") ${className}DeleteDTO param) {

        ${className} ${objectName} = new ${className}();
        BeanUtils.copyProperties(param, ${objectName});
        ${existDeleteFlag1}
        this.${objectName}DAO.getCommandMapper()
                .updateByPrimaryKeySelective(this.${objectName}Convert.domain2DO(${objectName}));
        return SingleResponse.of(${objectName});

    }
}